home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / chksum2.zip / CHKSUM.C next >
C/C++ Source or Header  |  1989-02-16  |  8KB  |  318 lines

  1. /*  /usr/bin/src/chksum.c 880118  NHA */
  2.  
  3. #define    DEBUG    0
  4. #define    MAJOR    'P'
  5. #define    MINOR    'C'
  6.  
  7. #include    <gen.h>
  8. #include    <string.h>
  9.  
  10. #define    SUCCESS    0
  11. #define    FAILURE    (!SUCCESS)
  12.  
  13.  
  14. #ifdef __STDC__
  15. import char                *gets(void *buffer);
  16. import int                open(char *filename, int mode);
  17. import int                read(int fd, void *buf, int count);
  18. import int                close(int fd);
  19. import char                *getenv(char *name);
  20. import void                exit(int status);
  21. import unsigned long    crc32buf(unsigned long initialSum,
  22.                                         unsigned char *buf, unsigned count);
  23. #else
  24. import char                *gets();
  25. import int                open();
  26. import int                read();
  27. import int                close();
  28. import char                *getenv();
  29. import void                exit();
  30. import unsigned long    crc32buf();
  31. #endif __STDC__
  32.  
  33. local unsigned char    buffer[BUFSIZ];            /* reads go into this buffer */
  34. local bool            showCount;                /* show the byte count [-c] */
  35. local bool            showError;                /* show Errors in any case */
  36. local bool            totalOnly;                /* don't show file sums [-t] */
  37. local bool            verbose;                /* print filenames [-v] */
  38. local bool            firstFile;                /* only true for 1st file */
  39. local unsigned        fileCount;                /* # of files processed OK */
  40. local unsigned        errorCount;                /* # of files with errors */
  41. local unsigned long    sum;                    /* checksum for a file */
  42. local unsigned long    grandSum;                /* checksum over all files */
  43. local unsigned long    byteCount;                /* byte count for a file */
  44. local unsigned long    grandByteCount;            /* byte count over all files */
  45.  
  46.  
  47.  
  48.  
  49. /*+     c h k s u m
  50.  * Calculate two chksums for the file.
  51.  * One is simply the chksum of the bytes in the file.
  52.  * The other is updating the grandSum with the bytes in the file.
  53.  * The grandSum is only updated for files after the first file.
  54.  * The byteCount and grandByteCount variables are also updated.
  55.  * Return FAILURE for file errors, else SUCCESS.
  56.  */
  57. local bool chksum(fd)
  58. int fd;                                        /* File Descriptor */
  59.     {
  60.     int            status;                        /* status returned from sys calls */
  61.  
  62.     printd(4, "chksum(%d)\n", fd);
  63.  
  64.     sum       = 0L;
  65.     while (1)
  66.         {
  67.         /* read next bufferload from the file */
  68.         status = read( fd, buffer, sizeof buffer );
  69.         printd(9, "read status=%d\n", status);
  70.         if (status < 0)
  71.             {
  72.             printd(4, "chksum(): returning FAILURE\n");
  73.             return FAILURE;
  74.             }
  75.         if (status == 0)
  76.             break;                            /* End Of File */
  77.  
  78.         /* update checksums */
  79.         sum = crc32buf(sum, buffer, (unsigned)status);
  80.         if ( ! firstFile )
  81.             grandSum = crc32buf(grandSum, buffer, (unsigned)status);
  82.  
  83.         /* update byte counts */
  84.         byteCount += (unsigned long)status;
  85.         grandByteCount += (unsigned long)status;
  86.  
  87.         printd(8, "sum=%08lx, grandSum=%08lx, byteCount=%ld, grandByteCount=%ld\n",
  88.           sum, grandSum, byteCount, grandByteCount);
  89.         }
  90.  
  91.     printd(4, "chksum(): returning SUCCESS with sum=%08lx,  grandSum=%08lx\n",
  92.       sum, grandSum);
  93.     return SUCCESS;
  94.     }
  95.  
  96.  
  97.  
  98. /*+        s u m F i l e
  99.  * Given a filename, calculate the checksum, do any necessary displaying,
  100.  * and update all the necessary global variables.
  101.  * If the filename is a NULL pointer or a pointer to '\0', we use stdin.
  102.  * In the event of file access errors, a sum of 0 is printed.
  103.  */
  104. local void sumFile(filename)
  105. char    *filename;
  106.     {
  107.     int fd;                                    /* File Descriptor */
  108.     char name[88];
  109.     bool isBad;                                /* YES for file errors */
  110.  
  111.     printd(4, "sumFile(%s)\n", filename);
  112.     byteCount = 0L;
  113.     
  114.     /* open input file.  NULL or ptr to '\0' is taken to mean standard input */
  115.     if (filename == NULL   ||   filename[0] == '\0')
  116.         {
  117.         strcpy(name, "--Stdin--");
  118.         fd = fileno(stdin);
  119.         }
  120.     else
  121.         {
  122.         strcpy(name, filename);
  123.         fd = open(filename, O_RDONLY);
  124.         if (fd < 0)
  125.             {
  126.             isBad = YES;
  127.             ++errorCount;
  128.             sum = 0L;
  129.                printd(2, "sumFile(%s): can't open file for read\n", filename);
  130.             if (showError)
  131.                 fprintf(stderr, "chksum: can't open \"%s\" for reading\n",
  132.                                 filename);
  133.             }
  134.         else
  135.             isBad = NO;
  136.         }
  137.  
  138.     /* calculate the checksum */
  139.     if (0 <= fd)
  140.         {
  141.         if (chksum(fd) == SUCCESS)
  142.             {
  143.             isBad = NO;
  144.             ++fileCount;
  145.             if (firstFile)
  146.                 {
  147.                 grandSum = sum;
  148.                 firstFile = NO;
  149.                 }
  150.             }
  151.         else
  152.             {
  153.             isBad = YES;
  154.             ++errorCount;
  155.             sum = 0L;
  156.             printd(2, "sumFile(%s): error reading file\n", name);
  157.             if (showError)
  158.                 fprintf(stderr, "chksum: error reading file \"%s\"\n",
  159.                                 filename);
  160.             }
  161.         if (fd != fileno(stdin))
  162.             close(fd);
  163.         }
  164.  
  165.     /* report the results */
  166.     if ( ! totalOnly)
  167.         {
  168.         printf("%08lx", sum);
  169.         if (showCount)
  170.             printf("  %10lu", byteCount);
  171.         if (verbose)
  172.             if (isBad)
  173.                 printf("   %s     *** ERROR ***", name);
  174.             else
  175.                 printf("   %s", name);
  176.         putchar('\n');
  177.         }
  178.     printd(4, "sumFile(): returning\n");
  179.     }
  180.  
  181.  
  182.  
  183. /*+        u s a g e
  184.  * Spew out the help message.
  185.  */
  186. local void usage()
  187.     {
  188.     fprintf(stderr, "chksum -- calculate 32-bit checksum for file(s), output to stdout\n");
  189.     fprintf(stderr, "Usage:    chksum   [-cehtv]    {file|--|-}...\n");
  190.     fprintf(stderr, "-c    Count bytes also\n");
  191.     fprintf(stderr, "-e    give extended Error reports on stderr\n");
  192.     fprintf(stderr, "-h    Help; give this help message and exit\n");
  193.     fprintf(stderr, "-t    Total only; don't list sum for each file\n");
  194.     fprintf(stderr, "-v    Verbose; list filenames along with checksums\n");
  195.     fprintf(stderr, "--    take filenames from stdin, 1 name per line\n");
  196.     fprintf(stderr, "-    take stdin as a file\n");
  197.     fprintf(stderr, "Filenames may be mixed with options.\n");
  198.     fprintf(stderr, "Exit status is the number of file errors encountered.\n");
  199.     exit(1);
  200.     }                                        /* usage */
  201.  
  202.  
  203.  
  204. /*+     m a i n
  205.  * See usage() for command line parameters.
  206.  */
  207. export int main(ac, av)
  208. int ac;
  209. char **av;
  210.     {
  211.     char    *p;
  212.     char    line[BUFSIZ];                    /* for reading from stdin */
  213.     char    switchar;
  214.  
  215.     /* initialize */
  216.     initdebug(&ac, &av, "/dev/con", "/dev/fifo", "**0");
  217.     showCount      = NO;                    /* default is no byte counts */
  218.     showError      = NO;                    /* default is no reports on stderr*/
  219.     totalOnly      = NO;                    /* default is show all checksums */
  220.     verbose        = NO;                    /* default is no filenames */
  221.     firstFile      = YES;                    /* no files checksummed yet */
  222.     fileCount      = 0;
  223.     errorCount     = 0;
  224.     grandSum       = 0L;
  225.     grandByteCount = 0L;
  226.     p = getenv("SWITCHAR");
  227.     if (p == NULL)
  228.         switchar = '-';
  229.     else
  230.         switchar = *p;
  231.  
  232.     /* process command line arguments */
  233.     for (--ac, ++av   ;   0 < ac   ;   --ac, ++av)
  234.         {
  235.         printd(7, "main():  ac = %d,  *av = '%s'\n", ac, *av); 
  236.         if (av[0][0] == switchar)
  237.             switch (av[0][1])
  238.                 {
  239.             case 'C':
  240.             case 'c':
  241.                 showCount = YES;
  242.                 break;
  243.             case 'E':
  244.             case 'e':
  245.                 showError = YES;
  246.                 break;
  247.             case 'H':
  248.             case 'h':
  249.                 usage();
  250.                 break;
  251.             case 'T':
  252.             case 't':
  253.                 totalOnly = YES;
  254.                 break;
  255.             case 'V':
  256.             case 'v':
  257.                 verbose = YES;
  258.                 break;
  259.             case '-':                        /* take filenames from stdin */
  260.                 while (gets(line) != NULL)
  261.                     sumFile(line);
  262.                 if (showError  &&  ferror(stdin))
  263.                     fprintf(stderr, "chksum: error reading standard input\n");
  264.                 clearerr(stdin);
  265.                 break;
  266.             case '\0':
  267.                 sumFile(NULL);                /* use standard input for file */
  268.                 break;
  269.             default:
  270.                 fprintf(stderr, "chksum: unknown option  %s\n", av[0]);
  271.                 }                            /* switch */
  272.         else
  273.             sumFile(av[0]);                    /* file */
  274.         }
  275.  
  276.  
  277.     /* put out the Grand Total */
  278.     if ((fileCount + errorCount)  ==  0)
  279.         usage();                            /* no files specified */
  280.     else if ((fileCount + errorCount)  ==  1)
  281.         {                                    /* one file specified */
  282.         if (totalOnly)
  283.             {
  284.             printf("%08lx", grandSum);
  285.             if (showCount)
  286.                 printf("  %10lu", grandByteCount);
  287.             putchar('\n');
  288.             }
  289.         }
  290.     else
  291.         {                                    /* multiple files specified */
  292.         if ( ! totalOnly)
  293.             {
  294.             printf("========");
  295.             if (showCount)
  296.                 printf("============");
  297.             putchar('\n');
  298.             }
  299.         printf("%08lx", grandSum);
  300.         if (showCount)
  301.             printf("  %10lu", grandByteCount);
  302.         if (verbose)
  303.             {
  304.             if (showCount)
  305.                 printf("   Grand Totals for %u files", fileCount);
  306.             else
  307.                 printf("   Grand Total for %u files", fileCount);
  308.             if (errorCount ==